package com.ibm.workplace.wcm.cqplugin.ui;

import java.text.*;
import java.util.*;

import org.eclipse.jface.action.*;
import org.eclipse.jface.preference.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

import com.ibm.workplace.wcm.cqplugin.*;
import com.ibm.workplace.wcm.cqplugin.preference.*;
import com.ibm.workplace.wcm.cqplugin.ui.actions.*;

public class BugTable extends Composite implements IDoubleClickListener/*kevin , ControlListener*/ {

    private Table bugTable = null;
    private TableViewer bugTableViewer = null;

    private String preferencesPrefix;

    public BugTable(Composite parent) {
        this(parent, "");
    }

    public BugTable(Composite parent, String preferencesPrefix) {
        super(parent, 0);

        this.preferencesPrefix = preferencesPrefix;

        GridLayout layout = new GridLayout(1, false);
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        setLayout(layout);

        bugTableViewer = new TableViewer(this, SWT.FULL_SELECTION | SWT.MULTI | SWT.FLAT);
        bugTable = bugTableViewer.getTable();
        bugTable.setLinesVisible(true);
        bugTable.setHeaderVisible(true);
        bugTableViewer.addDoubleClickListener(this);
        GridData gridData2 = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL);
        gridData2.horizontalSpan = 3;
        bugTable.setLayoutData(gridData2);

        createTableColumns(bugTableViewer);

        // this sets the column widths and column sorting
        applyTablePreferences();

        bugTableViewer.setContentProvider(new BugInfoContentProvider());
        bugTableViewer.setLabelProvider(new BugInfoLabelProvider());
        
        // We wait to add the column / sort listener until after the preferences have been applied
        BugTableSortListener sortListener = new BugTableSortListener(bugTableViewer);
        for (int i = 0; i < bugTable.getColumnCount(); i++) {
            bugTable.getColumn(i).addListener(SWT.Selection, sortListener);
            //kevin bugTable.getColumn(i).addControlListener(this);
        }
    }

    public void doubleClick(DoubleClickEvent arg0) {
    	if(Activator.DEBUG_ON)
    		System.out.println("doubleClick");
    	ViewDefectAction action = new ViewDefectAction(bugTableViewer);
    	if(Activator.DEBUG_ON)
    		System.out.println("action.run()");
    	action.run();
    }

    private void createTableColumns(TableViewer tableViewer) {
        Table table = tableViewer.getTable();

        TableColumn c1 = new TableColumn(table, 0);
        c1.setText("ID");
        c1.setWidth(getColumnWidthFromPreferences(0, 90));
        c1.setMoveable(true);
        c1.setResizable(true);
        c1.setData(BugTableComparator.COL_ID);

        c1 = new TableColumn(table, 0);
        c1.setText("State");
        c1.setWidth(getColumnWidthFromPreferences(1, 50));
        c1.setMoveable(true);
        c1.setResizable(true);
        c1.setData(BugTableComparator.COL_STATE);
        c1.setToolTipText("State");
        /*
        c1 = new TableColumn(table, 0);
        c1.setText("P");
        c1.setWidth(getColumnWidthFromPreferences(2, 25));
        c1.setMoveable(true);
        c1.setResizable(true);
        c1.setData(BugTableComparator.COL_PRIORITY);
        c1.setToolTipText("Priority");
		*/
        c1 = new TableColumn(table, 0);
        c1.setText("Severity");
        c1.setWidth(getColumnWidthFromPreferences(3, 70));
        c1.setMoveable(true);
        c1.setResizable(true);
        c1.setData(BugTableComparator.COL_SEVERITY);
        c1.setToolTipText("Severity");

        c1 = new TableColumn(table, 0);
        c1.setText("Description");
        c1.setWidth(getColumnWidthFromPreferences(4, 260));
        c1.setMoveable(true);
        c1.setResizable(true);
        c1.setData(BugTableComparator.COL_DESCRIPTION);

        c1 = new TableColumn(table, 0);
        c1.setText("Test_Type");
        c1.setWidth(getColumnWidthFromPreferences(5, 70));
        c1.setMoveable(true);
        c1.setResizable(true);
        c1.setData(BugTableComparator.COL_TESTTYPE);

        c1 = new TableColumn(table, 0);
        c1.setText("Originator");
        c1.setWidth(getColumnWidthFromPreferences(6, 90));
        c1.setMoveable(true);
        c1.setResizable(true);
        c1.setData(BugTableComparator.COL_ORIGINATOR);

        c1 = new TableColumn(table, 0);
        c1.setText("Owner");
        c1.setWidth(getColumnWidthFromPreferences(7, 90));
        c1.setMoveable(true);
        c1.setResizable(true);
        c1.setData(BugTableComparator.COL_OWNER);
    }

    private int getColumnWidthFromPreferences(int column, int defaultValue) {
        //int width = BugInfoPluginActivator.getDefault().getPreferenceStore().getInt(MessageFormat.format(preferencesPrefix + BugInfoPreferenceConstants.PREF_COLUMN_SIZE, new String[] { column + "" }));
    	//kevin-denny modified this? just use default width for now
    	int width = -1;
        if (width > 0) {
            return width;
        } else {
            return defaultValue;
        }
    }

    // This method resets all table-related preferences, including sort preferences and column width preferences
    private void resetPreferences() {
        IPreferenceStore store = Activator.getDefault().getPreferenceStore();

        store.setValue(preferencesPrefix + BugInfoPreferenceConstants.PREF_SORT_COLUMN, "id");
        store.setValue(preferencesPrefix + BugInfoPreferenceConstants.PREF_SORT_DIRECTION, SWT.DOWN);
        store.setValue(preferencesPrefix + BugInfoPreferenceConstants.PREF_COLUMN_ORDER, "");

        resetColumnWidthPreferences();
    }

    private void resetColumnWidthPreferences() {
        for (int i = 0; i < bugTable.getColumnCount(); i++) {
            Activator.getDefault().getPreferenceStore().setValue(MessageFormat.format(preferencesPrefix + BugInfoPreferenceConstants.PREF_COLUMN_SIZE, new String[] { i + "" }), 0);
        }
    }

    // This method resets the column width preferences and updates the actual GUI table
    public void resetColumnWidths() {
        resetColumnWidthPreferences();
        applyTablePreferences();
    }
    /*kevin
    public void controlMoved(ControlEvent event) {
        if (event.getSource() instanceof TableColumn) {
            saveTablePreferenes();
        }
    }

    public void controlResized(ControlEvent event) {
        if (event.getSource() instanceof TableColumn) {
            saveTablePreferenes();
        }
    }*/

    private void saveTablePreferenes() {
        IPreferenceStore store = Activator.getDefault().getPreferenceStore();

        store.setValue(preferencesPrefix + BugInfoPreferenceConstants.PREF_SORT_COLUMN, ((BugTableComparator) bugTableViewer.getComparator()).getColumn());
        store.setValue(preferencesPrefix + BugInfoPreferenceConstants.PREF_SORT_DIRECTION, ((BugTableComparator) bugTableViewer.getComparator()).direction);
        store.setValue(preferencesPrefix + BugInfoPreferenceConstants.PREF_COLUMN_ORDER, intArrayToString(bugTableViewer.getTable().getColumnOrder()));

        for (int i = 0; i < bugTable.getColumnCount(); i++) {
            TableColumn column = bugTable.getColumn(i);
            store.setValue(MessageFormat.format(preferencesPrefix + BugInfoPreferenceConstants.PREF_COLUMN_SIZE, new String[] { i + "" }), column.getWidth());
        }
    }

    private void applyTablePreferences() {
    	/*
        IPreferenceStore store = BugInfoPluginActivator.getDefault().getPreferenceStore();

        // Need to reset all table-related preferences if we have introduced a new column (or have removed a column)
        String str = store.getString(preferencesPrefix + BugInfoPreferenceConstants.PREF_COLUMN_ORDER);
        int[] columnOrdering = stringToIntArray(str);
        if (columnOrdering.length == 0 || columnOrdering.length != bugTable.getColumnCount()) {
            System.out.println("column ordering is non-existant OR then lenght is not right, resetting!");

            resetPreferences();
        } else {
            try {
                bugTableViewer.getTable().setColumnOrder(columnOrdering);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        BugTableComparator comparator = new BugTableComparator(store.getString(preferencesPrefix + BugInfoPreferenceConstants.PREF_SORT_COLUMN), store.getInt(preferencesPrefix + BugInfoPreferenceConstants.PREF_SORT_DIRECTION));

        // apply sort column and direction
        for (int i = 0; i < bugTableViewer.getTable().getColumnCount(); i++) {
            if (((String) bugTableViewer.getTable().getColumn(i).getData()).equals(comparator.getColumn())) {
                bugTableViewer.getTable().setSortColumn(bugTableViewer.getTable().getColumn(i));
                break;
            }
        }

        bugTableViewer.getTable().setSortDirection(comparator.getDirection());
        bugTableViewer.setComparator(comparator);
        */
    }

    private String intArrayToString(int[] array) {
        StringBuffer buffer = new StringBuffer();

        for (int i = 0; i < array.length; i++) {
            buffer.append(array[i]);
            //if (i < array.length - 1) {
            buffer.append(",");
            // }
        }

        return buffer.toString();
    }

    private int[] stringToIntArray(String str) {
        if (str == null) return new int[0];

        StringTokenizer st = new StringTokenizer(str, ",");
        int[] ret = new int[st.countTokens()];
        int index = 0;
        while (st.hasMoreElements()) {
            ret[index] = Integer.parseInt((String) st.nextElement());
            index++;
        }
        return ret;
    }

    private class BugTableComparator extends ViewerComparator implements Comparator {

        public static final String COL_ID = "id";
        public static final String COL_STATE = "state";
        public static final String COL_PRIORITY = "priority"; // low, medium, high
        public static final String COL_SEVERITY = "severity"; // 1 - big, 4 - suggestion
        public static final String COL_DESCRIPTION = "description";
        public static final String COL_TESTTYPE = "test_type";
        public static final String COL_OWNER = "owner";
        public static final String COL_ORIGINATOR = "originator";

        private String column = null;
        private int direction = 0;

        public BugTableComparator(String column, int direction) {
            super();

            this.column = column;
            this.direction = direction;
        }

        public int compare(Viewer viewer, Object e1, Object e2) {
            int ret = 0;
            
            if (this.column.equals(COL_ID)) {
                ret = ((IBugInfo) e1).getId().compareTo(((IBugInfo) e2).getId());
            } else if (this.column.equals(COL_STATE)) {
                ret = ((IBugInfo) e1).getState().toString().compareTo(((IBugInfo) e2).getState().toString());
            } else if (this.column.equals(COL_PRIORITY)) {
                ret = ((IBugInfo) e1).getPriority().toString().compareTo(((IBugInfo) e2).getPriority().toString()); // SHOULD LOOK AT THE numeric value of the code
            } else if (this.column.equals(COL_SEVERITY)) {
                ret = ((IBugInfo) e1).getSeverity().toString().compareTo(((IBugInfo) e2).getSeverity().toString()); // SHOULD LOOK AT THE numeric value of the code
            } else if (this.column.equals(COL_DESCRIPTION)) {
                ret = ((IBugInfo) e1).getDescription().compareTo(((IBugInfo) e2).getDescription());
            } else if (this.column.equals(COL_TESTTYPE)) {
                ret = ((IBugInfo) e1).getRelease().compareTo(((IBugInfo) e2).getRelease());
            } else if (this.column.equals(COL_OWNER)) {
                ret = ((IBugInfo) e1).getOwnerId().compareTo(((IBugInfo) e2).getOwnerId());
            } else if (this.column.equals(COL_ORIGINATOR)) {
                ret = ((IBugInfo) e1).getOriginatorId().compareTo(((IBugInfo) e2).getOriginatorId());
            }
            
            return (direction == SWT.DOWN ? ret * -1 : ret);
        }

        public String getColumn() {
            return column;
        }

        public int getDirection() {
            return direction;
        }

        public int compare(Object object1, Object object2) {
            return compare(null, object1, object2);
        }

    }

    private class BugTableSortListener implements Listener {

        private TableViewer viewer;

        public BugTableSortListener(TableViewer viewer) {
            super();

            this.viewer = viewer;
        }

        public void handleEvent(Event e) {
            TableColumn sortColumn = viewer.getTable().getSortColumn();
            TableColumn currentColumn = (TableColumn) e.widget;
            int dir = viewer.getTable().getSortDirection();
            if (sortColumn == currentColumn) {
                dir = dir == SWT.UP ? SWT.DOWN : SWT.UP;
            } else {
                viewer.getTable().setSortColumn(currentColumn);
                dir = SWT.UP;
            }

            String sortIdentifier = (String) currentColumn.getData();
            viewer.getTable().setSortDirection(dir);
            viewer.setComparator(new BugTableComparator(sortIdentifier, dir));

            saveTablePreferenes();
        }

    }

    public Table getTable() {
        return bugTable;
    }

    public TableViewer getTableViewer() {
        return bugTableViewer;
    }

    public MenuManager getDefaultMenuManager() {
        MenuManager mm = new MenuManager("context");
        /*kevin mm.add(new ViewDefectAction(bugTableViewer));
        mm.add(new ChangeDefectOwnerAction(bugTableViewer));
        mm.add(new AddCommentAction(bugTableViewer));
        mm.add(new Separator());
        mm.add(new ChatWithOwnerAction(bugTableViewer));
        mm.add(new ChatWithOriginatorAction(bugTableViewer));
        mm.add(new ChatWithOwnerAndOriginatorAction(bugTableViewer));
        //mm.add(new Separator());
        //mm.add(new RestoreColumnWidths(this));
        mm.add(new Separator());
        mm.add(new CopyBugNumbersAction(bugTableViewer));
        mm.add(new CopyBugInformationAction(bugTableViewer));*/

        return mm;
    }

}

